package top.zhangjianyong.tools.service.api.impl;

import cn.hutool.core.util.StrUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import top.zhangjianyong.tools.entity.Area;
import top.zhangjianyong.tools.entity.AreaDTO;
import top.zhangjianyong.tools.parm.AreaListParam;
import top.zhangjianyong.tools.service.api.AreaService;
import top.zhangjianyong.tools.service.mybatis.IAreaService;
import top.zhangjianyong.tools.utils.ApiResponse;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangjianyong
 * @since 2024/9/29 上午10:59
 */
@Service
public class AreaServiceImpl implements AreaService {

    @Autowired
    private IAreaService iAreaService;

    @Override
    public ApiResponse list(AreaListParam param) {
        AreaDTO root = new AreaDTO();
        List<String> areas = param.getAreas();
        List<Area> areaList = iAreaService.listByPrefix(areas);
        List<AreaDTO> areaDTOList = areaList.stream().map(area -> {
            AreaDTO areaDTO = new AreaDTO();
            BeanUtils.copyProperties(area, areaDTO);
            return areaDTO;
        }).collect(Collectors.toList());
        Map<Long, AreaDTO> cache = areaDTOList.stream()
                .collect(Collectors.toMap(AreaDTO::getCode, o -> o, (a, b) -> b));
        for (AreaDTO area : areaDTOList) {
            Long pcode = area.getPcode();
            AreaDTO p = cache.get(pcode);
            if (p != null) {
                p.addChild(area);
            }

        }
        List<AreaDTO> list = areaDTOList.stream().filter(area -> 1 == area.getLevel()).collect(Collectors.toList());
        root.addChild(list);
        List<String> res = areaTree2List(root);
        return ApiResponse.success(res);
    }

    @Override
    public ApiResponse ramdom(String areaCode, HttpServletResponse response) throws IOException {
        List<String> list = null;
        if (StrUtil.isNotBlank(areaCode)) {
            String[] split = areaCode.split(",");
            list = new ArrayList<>(Arrays.asList(split));
        } else {
            List<Area> areas = iAreaService.listByLevel(1);
            list = areas.stream().map(Area::getCode)
                    .map(String::valueOf).collect(Collectors.toList());
        }
        Collections.shuffle(list);
        String code = list.get(0);
        Area area = iAreaService.getByCode(code);
        String s = random(area, "");
        response.setContentType("text/html;charset=utf-8");
        try (PrintWriter writer = response.getWriter()) {
            writer.write(s);
        }
        return ApiResponse.success(s);
    }

    private String random(Area area, String name) {
        name = name + area.getName();
        List<Area> list = iAreaService.listByPcode(area.getCode());
        if (CollectionUtils.isEmpty(list)) return name;
        Collections.shuffle(list);
        Area next = list.get(0);
        return random(next, name);
    }


    private List<String> areaTree2List(AreaDTO root) {
        return areaTree2List(root, "", new ArrayList<>());
    }

    private List<String> areaTree2List(AreaDTO node, String prefix, List<String> list) {
        String name = node.getName();
        if (StrUtil.isNotBlank(name)) {
            prefix = prefix + name;
        }
        List<AreaDTO> child = node.getChild();
        if (CollectionUtils.isEmpty(child)) {
            list.add(prefix);
        } else {
            for (AreaDTO areaDTO : child) {
                areaTree2List(areaDTO, prefix, list);
            }
        }
        return list;
    }
}
